package cn.com.controller.frontController;

import cn.com.Enum.OrderStatus;
import cn.com.Enum.SessionAttr;
import cn.com.Enum.UserAuth;
import cn.com.annotation.Auth;
import cn.com.constant.Code;
import cn.com.db.model.*;
import cn.com.db.service.*;
import cn.com.util.*;
import cn.com.wxUtil.SendTemplateMessageUtil;
import cn.com.wxUtil.XMLUtil;
import cn.com.wxUtil.wxConstant;
import cn.com.wxUtil.refundUtil.RefundConstant;
import cn.com.wxUtil.refundUtil.WeiXinAtcion;
import cn.com.wxUtil.template.TemplateData;
import cn.com.wxUtil.template.WechatTemplate;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.interceptor.TransactionAspectSupport;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

@Auth(UserAuth.USER)
@RestController
@RequestMapping("/front/order")
public class OrderController {

	Logger logger = LoggerFactory.getLogger(OrderController.class);

	@Autowired
	OrderService orderService;
	@Autowired
	CartItemService cartItemService;
	@Autowired
	CartService cartService;
	@Autowired
	StoreService storeService;
	@Autowired
	GoodsService goodsService;
	@Autowired
	AddressService addressService;
	@Autowired
	OrderItemService orderItemService;
	@Autowired
	UserService userService;
	@Autowired
	WxPayResultService wxPayResultService;
	@Autowired
	WxRefundResultService wxRefundResultService;

	@RequestMapping(value = "/placeSingleOrder", method = RequestMethod.POST)
	public String placeOrder(HttpServletRequest request, @RequestParam("addressId") String addressId,
			@RequestParam("goodsId") String goodsId, @RequestParam("count") Integer count,
			@RequestParam("price") BigDecimal price, @RequestParam("remark") String remark) { // 这个是前端计算的算上配送费的总价格
		DataResult dataResult = new DataResult();
		String userAuthingId = (String) SessionUtil.getAttr(request, SessionAttr.USERAUTHINGID);
		Goods goods = goodsService.getGoodsById(goodsId);
		Store store = storeService.getStoreById(goods.getStore());
		Address address = addressService.getAddressById(addressId);
		if (!storeService.isAlive(store.getId())) {
			dataResult.setCode(Code.SERVER_ERROR);
			dataResult.setMessage("商家不处于接单状态");
			return JsonUtil.toJsonString(dataResult);
		}
		if (!goodsService.isAlive(goodsId)) {
			dataResult.setCode(Code.SERVER_ERROR);
			dataResult.setMessage("商品不存在,或商品已被下架");
			return JsonUtil.toJsonString(dataResult);
		}
		if (address == null) {
			dataResult.setCode(Code.SERVER_ERROR);
			dataResult.setMessage("收货地址不存在");
			return JsonUtil.toJsonString(dataResult);
		}
		Order order = new Order();
		order.setId(UidUtil.createUUID());
		order.setUser(userAuthingId);
		order.setStore(store.getId());
		order.setSeller(store.getSeller());
		order.setProvince(address.getProvince());
		order.setCity(address.getCity());
		order.setDistrict(address.getDistrict());
		order.setDetail(address.getDetail());
		order.setRecipient(address.getName());
		order.setPhone(address.getPhone());
		order.setPrice(goods.getPrice().multiply(new BigDecimal(count)));
		order.setFreight(store.getFreight());
		order.setStatus(OrderStatus.WAIT_PAY.getStatus());
		order.setCount(count);
		order.setRemark(remark);
		try {
			order.countTotalPrice();
		} catch (Exception e) {
			logger.warn("用户id为:{}的用户提交的订单由于无法计算出总价而无法生成;{}", userAuthingId, JSON.toJSONString(order));
			dataResult.setCode(Code.SERVER_ERROR);
			dataResult.setMessage("订单生成失败,无法计算出总价!");
			JsonUtil.toJsonString(dataResult);
		}
		order.setCreated_at(TimeUtil.getNowTimestamp());
		order.setUpdated_at(TimeUtil.getNowTimestamp());

		List<OrderItem> orderItems = new ArrayList<>();
		order.setItems(orderItems);
		OrderItem orderItem = new OrderItem();
		orderItem.setId(UidUtil.createUUID());
		orderItem.setGoods(goodsId);
		orderItem.setOrder(order.getId());
		orderItem.setCount(1);
		orderItem.setGoodsSlides(goods.getSlides());
		orderItem.setGoodsDesc(goods.getDescription());
		orderItem.setGoodsName(goods.getName());
		orderItem.setGoodsSize(goods.getSize());
		orderItem.setGoodsType(goods.getType());
		orderItem.setGoodsUnit(goods.getUnit());
		orderItem.setGoodsPrice(goods.getPrice());
		orderItem.setCreated_at(TimeUtil.getNowTimestamp());
		orderItems.add(orderItem);
		// 判断总价是否一样
		if (price.equals(order.getTotalPrice())) {
			orderService.createOrder(order);
		} else {
			dataResult.setCode(Code.SERVER_ERROR);
			dataResult.setMessage("总价错误或者价格变化,请重新下单!");
			return JsonUtil.toJsonString(dataResult);
		}
		dataResult.setCode(Code.SUCCESS);
		dataResult.setData(orderService.getOrderById(order.getId()));
		dataResult.setMessage("提交订单成功");
		return JsonUtil.toJsonString(dataResult);
	}

	@RequestMapping(path = "/placeOrder", method = RequestMethod.POST)
	public String placeOrder(HttpServletRequest request, @RequestParam("itemIds") String itemIds,
			@RequestParam("price") BigDecimal price, // 这个是算上配送费的总价格
			@RequestParam("addressId") String addressId, @RequestParam("remark") String remark) {
		DataResult dataResult = new DataResult();
		List<String> list = UidUtil.splitStringByComma(itemIds);
		if (list == null || list.size() == 0) {
			dataResult.setCode(Code.SERVER_ERROR);
			dataResult.setMessage("参数解析错误");
			return JsonUtil.toJsonString(dataResult);
		}
		List<CartItem> items = cartItemService.getCartItemByItemIdList(list);
		if (items == null || items.size() == 0) {
			dataResult.setCode(Code.SERVER_ERROR);
			dataResult.setMessage("请提交有效订单");
			return JsonUtil.toJsonString(dataResult);
		}
		Map<String, List<CartItem>> map = new HashMap<>();
		for (CartItem item : items) {
			if (!storeService.isAlive(item.getStore())) {
				dataResult.setCode(Code.SERVER_ERROR);
				dataResult.setMessage("商家不处于接单状态");
				return JsonUtil.toJsonString(dataResult);
			}
			if (!goodsService.isAlive(item.getGoods())) {
				dataResult.setCode(Code.SERVER_ERROR);
				dataResult.setMessage("商品不存在,或商品已被下架");
				return JsonUtil.toJsonString(dataResult);
			}
			// 对cartItem按照店铺进行分组
			List<CartItem> tempList = map.get(item.getStore());
			if (tempList == null) {
				tempList = new ArrayList<>();
				tempList.add(item);
				map.put(item.getStore(), tempList);
			} else {
				tempList.add(item);
			}
		}
		BigDecimal sum = cartService.countPrice(items);
		if (!sum.equals(price)) {
			dataResult.setCode(Code.SERVER_ERROR);
			dataResult.setMessage("商品价格变化");
			return JsonUtil.toJsonString(dataResult);
		}
		Address address = addressService.getAddressById(addressId);
		if (address == null) {
			dataResult.setCode(Code.SERVER_ERROR);
			dataResult.setMessage("收货地址不存在");
			return JsonUtil.toJsonString(dataResult);
		}
		String userAuthingId = (String) SessionUtil.getAttr(request, SessionAttr.USERAUTHINGID);
		List<String> orderIdList = new ArrayList<>();
		// 根据店铺分组生成订单
		for (String store : map.keySet()) {
			List<CartItem> storeCartItem = map.get(store);
			Store s = storeService.getStoreById(store);
			Order order = new Order();
			order.setId(UidUtil.createUUID());
			order.setUser(userAuthingId);
			order.setStore(store);
			order.setSeller(s.getSeller());
			order.setProvince(address.getProvince());
			order.setCity(address.getCity());
			order.setDistrict(address.getDistrict());
			order.setDetail(address.getDetail());
			order.setRecipient(address.getName());
			order.setPhone(address.getPhone());
			order.setFreight(s.getFreight());
			order.setPrice(cartService.countPrice(storeCartItem).subtract(s.getFreight()));// mxq
																							// 改
																							// 2018.4.10
																							// cartService.countPrice中计算了订单价格,这里要减去
			order.setStatus(OrderStatus.WAIT_PAY.getStatus());
			order.setCount(storeCartItem.size());
			order.setRemark(remark);
			try {
				order.countTotalPrice();
			} catch (Exception e) {
				logger.warn("用户id为:{}的用户提交的订单由于无法计算出总价而无法生成;{}", userAuthingId, JSON.toJSONString(order));
				dataResult.setCode(Code.SERVER_ERROR);
				dataResult.setMessage("订单生成失败,无法计算出总价!");
				JsonUtil.toJsonString(dataResult);
			}
			order.setCreated_at(TimeUtil.getNowTimestamp());
			order.setUpdated_at(TimeUtil.getNowTimestamp());
			List<OrderItem> orderItems = new ArrayList<>();
			order.setItems(orderItems);
			for (CartItem item : storeCartItem) {
				OrderItem orderItem = new OrderItem();
				Goods goods = goodsService.getGoodsById(item.getGoods());
				orderItem.setId(UidUtil.createUUID());
				orderItem.setGoods(item.getGoods());
				orderItem.setOrder(order.getId());
				orderItem.setCount(item.getCount());
				orderItem.setGoodsName(goods.getName());
				orderItem.setGoodsSize(goods.getSize());
				orderItem.setGoodsType(goods.getType());
				orderItem.setGoodsUnit(goods.getUnit());
				orderItem.setGoodsPrice(goods.getPrice());
				orderItem.setGoodsDesc(goods.getDescription());
				orderItem.setGoodsSlides(goods.getSlides());
				orderItem.setCreated_at(TimeUtil.getNowTimestamp());
				orderItems.add(orderItem);
			}
			orderService.createOrder(order);
			orderIdList.add(order.getId());
		}
		cartItemService.deleteCartItems(list);
		dataResult.setData(orderIdList); // mxq 2018.4.5 添加回显idlist
		dataResult.setTotal(orderIdList.size());
		dataResult.setCode(Code.SUCCESS);
		dataResult.setMessage("提交订单成功");
		return JsonUtil.toJsonString(dataResult);
	}

	@RequestMapping(value = "/{id}", method = RequestMethod.GET)
	public String viewOrder(@PathVariable("id") String id) {
		DataResult dataResult = new DataResult();
		Order order = orderService.getOrderById(id);
		if (order == null) {
			dataResult.setCode(Code.SERVER_ERROR);
			dataResult.setMessage("订单不存在");
			return JsonUtil.toJsonString(dataResult);
		}
		dataResult.setData(order);
		dataResult.setCode(Code.SUCCESS);
		dataResult.setMessage("返回成功");
		return JsonUtil.toJsonString(dataResult);
	}

	@RequestMapping(value = "/cancel", method = RequestMethod.POST)
	public String cancel(HttpServletRequest request, @RequestParam("orderId") String orderId) throws Exception {
		DataResult dataResult = new DataResult();
		String userAuthingId = (String) SessionUtil.getAttr(request, SessionAttr.USERAUTHINGID);
		Order order = orderService.getOrderById(orderId);
		if (order == null) {
			dataResult.setCode(Code.SERVER_ERROR);
			dataResult.setMessage("订单不存在");
			return JsonUtil.toJsonString(dataResult);
		}
		if (!order.getUser().equals(userAuthingId)) {
			dataResult.setCode(Code.FORBIDDEN);
			dataResult.setMessage("操作失败");
			return JsonUtil.toJsonString(dataResult);
		}
		if (!order.getStatus().equals(OrderStatus.WAIT_ORDERS.getStatus())) {
			dataResult.setCode(Code.FORBIDDEN);
			dataResult.setMessage("当前状态无法取消订单");
			return JsonUtil.toJsonString(dataResult);
		}

		/************** 退款 ********************/
		WxPayResult payResult = wxPayResultService.getPayResultByOrderId(orderId);
		if (payResult == null) {
			dataResult.setCode(Code.FORBIDDEN);
			dataResult.setMessage("该订单未支付成功,请重新支付");
			return JsonUtil.toJsonString(dataResult);
		}
		String out_trade_no = payResult.getId(); // 退款订单
		String xmlWxInfo = payResult.getWx_meta_info();
		Map xmlMap = XMLUtil.doXMLParse(xmlWxInfo);
		String total_fee = (String) xmlMap.get("cash_fee");
		BigDecimal all_total_fee = new BigDecimal(total_fee); // 订单金额
		BigDecimal refund_fee = order.getTotalPrice().movePointRight(2); // 退款金额
		String appid = wxConstant.APPID; // 微信小程序--》“开发者ID”
		String mch_id = wxConstant.MCH_ID; // 商户号，将该值赋值给partner
		String key = wxConstant.PAY_KEY; // 微信支付商户平台登录）--》“API安全”--》“API密钥”--“设置密钥”（设置之后的那个值就是partnerkey，32位）

		Map<String, String> refundmap = WeiXinAtcion.wechatRefund(mch_id, appid, key, out_trade_no, all_total_fee,
				refund_fee);

		String resultJson = JSON.toJSONString(refundmap);
		// 退款之后业务逻辑 : 修改订单状态,新建数据库表
		WxRefundResult wxRefundResult = new WxRefundResult();
		if (refundmap.get("return_code").equals("SUCCESS")) {
			if (refundmap.get("result_code").equals("FAIL")) {
				// 失败
				// dataResult.setData(refundmap.get("err_code_des"));
				wxRefundResult.setId(UidUtil.createUUID());
				wxRefundResult.setOrder(orderId);
				wxRefundResult.setSeller(order.getSeller());
				wxRefundResult.setUser(order.getUser());
				wxRefundResult.setStore(order.getStore());
				wxRefundResult.setWx_meta_info(resultJson); // 存的json
				wxRefundResult.setType(RefundConstant.TYPE);
				wxRefundResult.setResult(false);
				wxRefundResult.setCreated_at(TimeUtil.getNowTimestamp());
				wxRefundResult.setUpdated_at(TimeUtil.getNowTimestamp());
				wxRefundResultService.createRefundResult(wxRefundResult);
				dataResult.setCode(Code.REFUND_FAIL);
				dataResult.setMessage("「取消订单失败，原因：退款失败，请稍候再试」");
				return JsonUtil.toJsonString(dataResult);
			} else {
				wxRefundResult.setId(UidUtil.createUUID());
				wxRefundResult.setOrder(orderId);
				wxRefundResult.setSeller(order.getSeller());
				wxRefundResult.setUser(order.getUser());
				wxRefundResult.setStore(order.getStore());
				wxRefundResult.setWx_meta_info(resultJson); // 存的json
				wxRefundResult.setType(RefundConstant.TYPE);
				wxRefundResult.setResult(true);
				wxRefundResult.setCreated_at(TimeUtil.getNowTimestamp());
				wxRefundResult.setUpdated_at(TimeUtil.getNowTimestamp());
				wxRefundResultService.createRefundResult(wxRefundResult);
			}
		} else {
			// 失败
			// dataResult.setData(refundmap.get("return_ms"));
			wxRefundResult.setId(UidUtil.createUUID());
			wxRefundResult.setOrder(orderId);
			wxRefundResult.setSeller(order.getSeller());
			wxRefundResult.setUser(order.getUser());
			wxRefundResult.setStore(order.getStore());
			wxRefundResult.setWx_meta_info(resultJson); // 存的json
			wxRefundResult.setType(RefundConstant.TYPE);
			wxRefundResult.setResult(false);
			wxRefundResult.setCreated_at(TimeUtil.getNowTimestamp());
			wxRefundResult.setUpdated_at(TimeUtil.getNowTimestamp());
			wxRefundResultService.createRefundResult(wxRefundResult);
			dataResult.setCode(Code.REFUND_FAIL);
			dataResult.setMessage("「取消订单失败，原因：退款失败，请稍候再试」");
			return JsonUtil.toJsonString(dataResult);
		}
		/**********************************/
		orderService.updateOrderStatus(orderId, OrderStatus.CANCEL.getStatus());

		dataResult.setCode(Code.SUCCESS);
		dataResult.setMessage("取消订单成功");
		return JsonUtil.toJsonString(dataResult);
	}

	@RequestMapping(value = "/confirm", method = RequestMethod.POST)
	public String confirm(HttpServletRequest request, @RequestParam("orderId") String orderId) {
		DataResult dataResult = new DataResult();
		String userAuthingId = (String) SessionUtil.getAttr(request, SessionAttr.USERAUTHINGID);
		Order order = orderService.getOrderById(orderId);
		if (order == null) {
			dataResult.setCode(Code.SERVER_ERROR);
			dataResult.setMessage("订单不存在");
			return JsonUtil.toJsonString(dataResult);
		}
		if (!order.getUser().equals(userAuthingId)) {
			dataResult.setCode(Code.FORBIDDEN);
			dataResult.setMessage("操作失败");
			return JsonUtil.toJsonString(dataResult);
		}
		if (!order.getStatus().equals(OrderStatus.TRANING.getStatus())) {
			dataResult.setCode(Code.FORBIDDEN);
			dataResult.setMessage("当前状态无法确认订单");
			return JsonUtil.toJsonString(dataResult);
		}
		orderService.updateOrderStatus(orderId, OrderStatus.COMPLETE.getStatus());
		/******************* 发送模板消息 ************************/
		WechatTemplate w = new WechatTemplate();
		String userId = order.getUser();
		User user = userService.getUserAuthingId(userId);
		String openid = user.getOpenId();
		w.setTouser(openid);
		String prepayId = wxPayResultService.getPrepayIdByOrderId(orderId);
		w.setForm_id(prepayId);
		String page = "/pages/order";
		w.setPage(page);
		w.setTemplate_id(wxConstant.TEMPLATE_ID_RECEIPTGOODS);
		LinkedHashMap<String, TemplateData> map = new LinkedHashMap<>();
		TemplateData t1 = new TemplateData();
		String time = order.getUpdated_at().toString();
		time = time.substring(0, time.indexOf("."));
		t1.setValue("您已确认收货");
		t1.setColor("#000000");
		map.put("keyword1", t1);
		TemplateData t2 = new TemplateData();
		t2.setValue(order.getId());
		t2.setColor("#000000");
		map.put("keyword2", t2);
		TemplateData t3 = new TemplateData();
		List<OrderItem> items = order.getItems();
		StringBuffer sb = new StringBuffer("");
		for (OrderItem orderItem : items) {
			sb.append(orderItem.getGoodsName()).append(",");
		}
		t3.setValue(sb.substring(0, sb.length() - 1)); // 商品详情
		t3.setColor("#000000");
		map.put("keyword3", t3);
		TemplateData t5 = new TemplateData();
		t5.setValue(order.getPhone());
		t5.setColor("#000000");
		map.put("keyword4", t5);
		TemplateData t6 = new TemplateData();
		Address address = addressService.getUserDefAddress(userId);
		t6.setValue(address.getName());
		t6.setColor("#000000");
		map.put("keyword5", t6);
		TemplateData t7 = new TemplateData();
		t7.setValue(order.getTotalPrice().toString());
		t7.setColor("#000000");
		map.put("keyword6", t7);
		TemplateData t8 = new TemplateData();
		t8.setValue(address.getPhone());
		t8.setColor("#000000");
		map.put("keyword7", t8);
		w.setData(map);
		String jsonTemplate = JSONObject.toJSON(w).toString();
		System.out.println(jsonTemplate);
		try {
			SendTemplateMessageUtil.send(jsonTemplate);
		} catch (Exception e) {
			// message += ",但距离支付完成超过七天将不发送";
		}

		/*******************************************/
		dataResult.setCode(Code.SUCCESS);
		dataResult.setMessage("确认订单成功");
		return JsonUtil.toJsonString(dataResult);
	}

	@RequestMapping(method = RequestMethod.POST)
	public String getUserOrder(HttpServletRequest request, Order order, @RequestParam("page") Integer page,
			@RequestParam("count") Integer count) {
		DataResult dataResult = new DataResult(page, count);
		String userAuthingId = (String) SessionUtil.getAttr(request, SessionAttr.USERAUTHINGID);
		order.setUser(userAuthingId);
		dataResult.setData(orderService.getOrder(order, page, count));
		dataResult.setTotal(orderService.countOrder(order));
		dataResult.setCode(Code.SUCCESS);
		dataResult.setMessage("返回成功");
		return JsonUtil.toJsonString(dataResult);
	}

}
